package cn.fulong.sso.client.manager.impl;

import cn.fulong.sso.client.manager.AbstractSessionManager;
import cn.fulong.sso.client.utils.StringSelfUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.session.data.redis.RedisOperationsSessionRepository;

import javax.servlet.http.HttpSession;
import java.util.concurrent.TimeUnit;

/**
 * @Version 1.0
 * @Author: 云树
 * @Desc: spring session 共享会话管理器实现类
 * @Date: 2019/9/6 15:03
 * @Modify 云树
 * @ModifyDate 2019/9/6 15:03
 * @since 1.0
 */
@Slf4j
public class SpringSessionRedisSessionManager extends AbstractSessionManager {

    private StringRedisTemplate stringRedisTemplate;
    private RedisOperationsSessionRepository redisOperationsSessionRepository;
    private final String TOKEN_PREFIX = "spring:session:token:";

    /**
     * redis记录token sessionId过期失效时间,此值一定要比Session失效时间大
     */
    private long tokenExpiresMinutes;

    public SpringSessionRedisSessionManager(StringRedisTemplate stringRedisTemplate, RedisOperationsSessionRepository redisOperationsSessionRepository) {
        this(stringRedisTemplate, redisOperationsSessionRepository, 12 * 60);
    }

    public SpringSessionRedisSessionManager(StringRedisTemplate stringRedisTemplate, RedisOperationsSessionRepository redisOperationsSessionRepository, long tokenExpiresMinutes) {
        this.stringRedisTemplate = stringRedisTemplate;
        this.redisOperationsSessionRepository = redisOperationsSessionRepository;
        this.tokenExpiresMinutes = tokenExpiresMinutes;
    }

    /**
     * @param token
     * @return token对应的查询sessionId的key
     */
    private String getTokenKey(String token) {
        return TOKEN_PREFIX + token;
    }

    /**
     * 根据token清除本地session会话
     * @param token
     * @return
     */
    @Override
    public boolean removeSessionManagerByToken(String token) {
        String sessionId = this.stringRedisTemplate.opsForValue().get(getTokenKey(token));
        if (StringSelfUtil.isNotBlank(sessionId)) {
            //删除spring session共享记录相关记录
            redisOperationsSessionRepository.delete(sessionId);
            return true;
        }
        this.stringRedisTemplate.delete(token);
        log.warn("【根据token清除本地Session】token={}，未查询到sessionId", token);
        return false;
    }

    @Override
    public boolean addTokenSessionStorage(String token, HttpSession sessionStorage) {
        this.stringRedisTemplate.opsForValue().set(getTokenKey(token), sessionStorage.getId(), tokenExpiresMinutes, TimeUnit.MINUTES);
        return true;
    }

    @Override
    public boolean removeTokenMappingSessionByToken(String token) {
        if (StringSelfUtil.isNotBlank(token)) {
            this.stringRedisTemplate.delete(getTokenKey(token));
        }
        return true;
    }
}
